// import com.alibaba.druid.sql.ast.*;
// import com.alibaba.druid.sql.visitor.SQLASTVisitor;

// import java.util.ArrayList;
// import java.util.List;

#include "SQLMergeStatement.h"
#include "SQLErrorLoggingClause.h"
#include "../../visitor/SQLASTVisitor.h"
#include "../../../utils/listTran.h"
#include "SQLUpdateSetItem.h"
#include "SQLTableSource.h"
#include "SQLExprTableSource.h"

SQLMergeStatement_MergeUpdateClause::SQLMergeStatement_MergeUpdateClause()
{
  items = std::make_shared<std::list<SQLUpdateSetItem_ptr>>();
}
SQLUpdateSetItem_list_ptr SQLMergeStatement_MergeUpdateClause::getItems()
{
  return items;
}

void SQLMergeStatement_MergeUpdateClause::addItem(SQLUpdateSetItem_ptr item)
{
  if (item != nullptr)
  {
    item->setParent(SharedObject(SQLMergeStatement_MergeUpdateClause));
  }
  this->items->push_back(item);
}

BOOL_ptr SQLMergeStatement_MergeUpdateClause::isDelete()
{
  return delete_;
}

void SQLMergeStatement_MergeUpdateClause::setDelete(BOOL_ptr delete_)
{
  this->delete_ = delete_;
}

SQLExpr_ptr SQLMergeStatement_MergeUpdateClause::getWhere()
{
  return where;
}

void SQLMergeStatement_MergeUpdateClause::setWhere(SQLExpr_ptr where)
{
  this->where = where;
}

SQLExpr_ptr SQLMergeStatement_MergeUpdateClause::getDeleteWhere()
{
  return deleteWhere;
}

void SQLMergeStatement_MergeUpdateClause::setDeleteWhere(SQLExpr_ptr x)
{
  if (x != nullptr)
  {
    x->setParent(SharedObject(SQLMergeStatement_MergeUpdateClause));
  }
  this->deleteWhere = x;
}

// @Override
void SQLMergeStatement_MergeUpdateClause::accept0(SQLASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(SQLMergeStatement_MergeUpdateClause)))
  {
    SQLObject_list_ptr tmp = ListTran::tran_class<SQLUpdateSetItem, SQLObject>(items);
    acceptChild(visitor, tmp);
    acceptChild(visitor, where);
    acceptChild(visitor, deleteWhere);
  }
  visitor->endVisit(SharedObject(SQLMergeStatement_MergeUpdateClause));
}

SQLMergeStatement_MergeInsertClause::SQLMergeStatement_MergeInsertClause()
{
  columns = std::make_shared<std::list<SQLExpr_ptr>>();
  values = std::make_shared<std::list<SQLExpr_ptr>>();
}
// @Override
void SQLMergeStatement_MergeInsertClause::accept0(SQLASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(SQLMergeStatement_MergeInsertClause)))
  {
    SQLObject_list_ptr tmp1 = ListTran::tran_class<SQLExpr, SQLObject>(columns);
    acceptChild(visitor, tmp1);
    SQLObject_list_ptr tmp2 = ListTran::tran_class<SQLExpr, SQLObject>(values);
    acceptChild(visitor, tmp2);
    acceptChild(visitor, where);
  }
  visitor->endVisit(SharedObject(SQLMergeStatement_MergeInsertClause));
}

SQLExpr_list_ptr SQLMergeStatement_MergeInsertClause::getColumns()
{
  return columns;
}

void SQLMergeStatement_MergeInsertClause::setColumns(SQLExpr_list_ptr columns)
{
  this->columns = columns;
}

SQLExpr_list_ptr SQLMergeStatement_MergeInsertClause::getValues()
{
  return values;
}

void SQLMergeStatement_MergeInsertClause::setValues(SQLExpr_list_ptr values)
{
  this->values = values;
}

SQLExpr_ptr SQLMergeStatement_MergeInsertClause::getWhere()
{
  return where;
}

void SQLMergeStatement_MergeInsertClause::setWhere(SQLExpr_ptr x)
{
  if (x != nullptr)
  {
    x->setParent(SharedObject(SQLMergeStatement_MergeInsertClause));
  }
  this->where = x;
}

SQLMergeStatement::SQLMergeStatement()
{
  hints = std::make_shared<std::list<SQLHint_ptr>>();
}
void SQLMergeStatement::accept0(SQLASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(SQLMergeStatement)))
  {
    acceptChild(visitor, into);
    acceptChild(visitor, using_);
    acceptChild(visitor, on);
    acceptChild(visitor, updateClause);
    acceptChild(visitor, insertClause);
    acceptChild(visitor, std::dynamic_pointer_cast<SQLObject>(errorLoggingClause));
  }
  visitor->endVisit(SharedObject(SQLMergeStatement));
}

string_ptr SQLMergeStatement::getAlias()
{
  return into->getAlias();
}

SQLTableSource_ptr SQLMergeStatement::getInto()
{
  return into;
}

void SQLMergeStatement::setInto(SQLName_ptr into)
{
  this->setInto(SQLExprTableSource_ptr(new SQLExprTableSource(into)));
}

void SQLMergeStatement::setInto(SQLTableSource_ptr into)
{
  if (into != nullptr)
  {
    into->setParent(SharedObject(SQLMergeStatement));
  }
  this->into = into;
}

SQLTableSource_ptr SQLMergeStatement::getUsing()
{
  return using_;
}

void SQLMergeStatement::setUsing(SQLTableSource_ptr using_)
{
  this->using_ = using_;
}

SQLExpr_ptr SQLMergeStatement::getOn()
{
  return on;
}

void SQLMergeStatement::setOn(SQLExpr_ptr on)
{
  this->on = on;
}

SQLMergeStatement_MergeUpdateClause_ptr SQLMergeStatement::getUpdateClause()
{
  return updateClause;
}

void SQLMergeStatement::setUpdateClause(SQLMergeStatement_MergeUpdateClause_ptr updateClause)
{
  this->updateClause = updateClause;
}

SQLMergeStatement_MergeInsertClause_ptr SQLMergeStatement::getInsertClause()
{
  return insertClause;
}

void SQLMergeStatement::setInsertClause(SQLMergeStatement_MergeInsertClause_ptr insertClause)
{
  this->insertClause = insertClause;
}

SQLErrorLoggingClause_ptr SQLMergeStatement::getErrorLoggingClause()
{
  return errorLoggingClause;
}

void SQLMergeStatement::setErrorLoggingClause(SQLErrorLoggingClause_ptr errorLoggingClause)
{
  this->errorLoggingClause = errorLoggingClause;
}

SQLHint_list_ptr SQLMergeStatement::getHints()
{
  return hints;
}
